import _ from 'lodash'
import Vue from 'vue'
import API from 'app/api'
import { FileTypes } from 'utils'
import FileNode, { ROOT_PATH, bootstrapRootNode, focusedNodes } from './file-node'

// 变动名称
const loadFileNode = 'loadFileNode'
const selectFileNode = 'selectFileNode'
const highlightDirNode = 'highlightDirNode'
const removeNode = 'removeNode'
const openContextMenu = 'openContextMenu'
const closeContextMenu = 'closeContextMenu'
const toggleNodeFold = 'toggleNodeFold'

export default {
  namespaced: true,
  state: {
    nodes: FileNode.nodes,
    contextMenuState: {
      isActive: false,
      pos: { x: 0, y: 0 },
      contextNode: null
    }
  },

  mutations: {
    [loadFileNode]: (state, nodeData) => {
      if (!FileNode.nodes[ROOT_PATH]) {
        bootstrapRootNode()
      }
      nodeData.forEach(nodeInfo => {
        let nextNodeInfo = { ...nodeInfo, path: ROOT_PATH + nodeInfo.path }
        const curNodeInfo = FileNode.nodes[nextNodeInfo.path]
        if (curNodeInfo) {
          nextNodeInfo = { ...curNodeInfo, ...nextNodeInfo }
        }
        FileNode.nodes[nextNodeInfo.path] = new FileNode(nextNodeInfo)
      })
      FileNode.root.reconstruct()
      state.nodes = { ...FileNode.nodes }
    },

    [selectFileNode]: (state, nodeOrOffset) => {
      let multiSelect = false
      let offset, node
      if (typeof nodeOrOffset === 'number') {
        offset = nodeOrOffset
      } else {
        node = nodeOrOffset
      }
      if (offset === 1) {
        node = focusedNodes()[0].next(true)
      } else if (offset === -1) {
        node = focusedNodes()[0].prev(true)
      }
      if (!multiSelect) {
        FileNode.root.unfocus()
        FileNode.root.forEachDescendant(childNode => childNode.unfocus())
      }
      node.focus()
      state.nodes = { ...FileNode.nodes }
    },

    [openContextMenu]: (state, payload) => {
      // const { pos, contextNode } = { payload }
      let contextMenuState = payload
      contextMenuState.isActive = true
      state.contextMenuState = contextMenuState
    },
    [closeContextMenu]: (state) => {
      state.contextMenuState.isActive = false
    },
    [toggleNodeFold]: (state, payload) => {
      let [node, shouldBeFolded, deep] = payload
      if (!node.isDir) return
      let isFolded
      if (typeof shouldBeFolded === 'boolean') {
        isFolded = shouldBeFolded
      } else {
        isFolded = !node.isFolded
      }
      node.toggleFold(isFolded)
      if (deep) {
        node.forEachDescendant(childNode => {
          childNode.toggleFold(isFolded)
        })
      }
      state.nodes = { ...FileNode.nodes }
    },

    [highlightDirNode]: (state, breadcrumbs) => {
      Vue.set(state, 'breadcrumb_data', breadcrumbs)
    },
    [removeNode]: (state, breadcrumbs) => {
      Vue.set(state, 'breadcrumb_data', breadcrumbs)
    }
  },

  actions: {
    initializeFileTree ({ commit }) {
      API.fetchNodeByPath('/').then(data => {
        commit(loadFileNode, data)
      })
    },
    openFileNode ({ commit }, [node, shouldBeFolded = null, deep = false]) {
      if (node.isDir) {
        // 文件夹打开
        if (node.children.length) {
          commit(toggleNodeFold, [node, shouldBeFolded, deep])
        } else {
          API.fetchNodeByPath(node.path).then(data => {
            commit(loadFileNode, data)
          }).then(() => {
            commit(toggleNodeFold, [node, shouldBeFolded, deep])
          })
        }
      } else {
        // 打开文件
        const fileType = FileTypes.getFileType(node.contentType)
        if (fileType === 'TEXT') {
          API.readFile(node.path).then(data => {
            let tab = {
              id: _.uniqueId('tab_'),
              type: 'editor',
              title: node.name,
              path: node.path,
              icon: 'fa fa-file-o',
              content: { body: data.content },
              contentType: node.contentType
            }
            commit('tab/tabCreate', tab, { root: true })
          })
        } else {
          let tab = {
            id: _.uniqueId('tab_'),
            type: 'editor',
            title: node.name,
            path: node.path,
            icon: 'fa fa-file-o',
            contentType: node.contentType,
            size: node.size
          }
          commit('tab/tabCreate', tab, { root: true })
        }
      }
    }
  }
}
